package service

import (
	"context"
	servicetoken "e-commerce/services/auth-service/api/servietoken"
	orderpb "e-commerce/services/order-service/api/pb"
	"log"
	"os"

	"go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc"
	"google.golang.org/grpc"
	"google.golang.org/grpc/credentials/insecure"
	"google.golang.org/grpc/metadata"
	"gopkg.in/yaml.v3"
)

type OrderClient struct {
	client orderpb.OrderServiceClient
	conn   *grpc.ClientConn
}

type PaymentService struct {
	OrderClient *OrderClient
}

type Config struct {
	OrderService order_service `yaml:"order_service"`
}

type order_service struct {
	Addr string `yaml:"addr"`
}

func NewPaymentService(configPath string) (*PaymentService, error) {
	yamlFile, err := os.ReadFile(configPath)
	if err != nil {
		return nil, err
	}
	var config Config
	err = yaml.Unmarshal(yamlFile, &config)
	if err != nil {
		return nil, err
	}
	log.Println("order service config: ", config)
	log.Println("order service addr: ", config.OrderService.Addr)
	conn, err := grpc.NewClient(
		config.OrderService.Addr,
		grpc.WithTransportCredentials(insecure.NewCredentials()),
		grpc.WithStatsHandler(otelgrpc.NewClientHandler()),
	)
	if err != nil {
		return nil, err
	} else {
		log.Println("order service conn: ", conn)
	}
	return &PaymentService{
		OrderClient: &OrderClient{
			client: orderpb.NewOrderServiceClient(conn),
			conn:   conn,
		},
	}, nil
}

func (s *PaymentService) MarkOrderPaid(ctx context.Context, orderID int64, success bool) error {
	//往context添加token
	ctx = metadata.AppendToOutgoingContext(ctx, "authorization", "Bearer "+servicetoken.ServiceTokens["payment-service"])
	//获取order订单状态
	orderResp, err := s.OrderClient.client.GetOrder(ctx, &orderpb.GetOrderRequest{OrderId: orderID})
	if err != nil {
		return err
	}
	//如果订单状态为reserved，则调用MarkOrderPaid方法
	if orderResp.Order.Status == "reserved" {
		_, err := s.OrderClient.client.MarkOrderPaid(ctx, &orderpb.MarkOrderPaidRequest{OrderId: orderID, Success: success})
		if err != nil {
			return err
		}
	}
	return nil
}

func (s *PaymentService) MarkOrderPaidSuccess(ctx context.Context, orderID int64) error {
	return s.MarkOrderPaid(ctx, orderID, true)
}

func (s *PaymentService) MarkOrderPaidFailed(ctx context.Context, orderID int64) error {
	return s.MarkOrderPaid(ctx, orderID, false)
}
